/**
 * NPC集群数据采集脚本
 * 功能：
 * 1. 从数据库获取城市siteId列表
 * 2. 发送1437指令移动到城市
 * 3. 接收200指令获取NPC集群列表
 * 4. 发送713指令获取NPC集群详情
 * 5. 保存数据为yeguai0923.json
 */

const WebSocket = require('ws');
const fs = require('fs');
const path = require('path');
const mysql = require('mysql2/promise');

// 测试配置
const CONFIG = {
    server: {
        host: 'cd521.xin',
        port: 8207,
        protocol: 'ws'
    },
    // 直接使用token连接
    token: '1ed75003262a59e70222e4ad99466360',
    // 数据库配置
    database: {
        host: '43.143.253.188',
        port: 3306,
        user: 'nextjs',
        password: 'yEAiRE2jcxTyRBy5',
        database: 'nextjs',
        charset: 'utf8mb4'
    }
};

class NPCClusterCollector {
    constructor() {
        this.ws = null;
        this.currentRequest = null;
        this.npcClusters = {}; // 存储所有NPC集群数据
        this.citySites = []; // 城市站点列表
        this.currentCity = null;
        this.pendingNPCs = []; // 待查询详情的NPC列表
    }

    // 从数据库获取城市站点列表
    async getCitySitesFromDB() {
        const conn = await mysql.createConnection(CONFIG.database);
        try {
            console.log('📊 从数据库获取城市站点列表...');

            const [sites] = await conn.execute(`
                SELECT 
                    id,
                    name,
                    type_id,
                    area_id,
                    ss
                FROM map_sites 
                WHERE type_id IN (1, 2, 6)  -- 1:城市, 2:关卡, 6:村庄
                ORDER BY area_id, id
            `);

            this.citySites = sites;
            console.log(`✅ 找到 ${sites.length} 个城市/站点:`);
            sites.forEach(site => {
                console.log(`  - ${site.id}: ${site.name} (类型:${site.type_id})`);
            });

            return sites;
        } catch (error) {
            console.error('❌ 查询数据库失败:', error.message);
            throw error;
        } finally {
            await conn.end();
        }
    }

    // 发送1437指令移动到城市
    async moveToCity(siteId, timeoutMs = 5000) {
        return new Promise((resolve, reject) => {
            try {
                if (this.currentRequest) {
                    return reject(new Error('上一个请求尚未完成'));
                }

                const payload = { c: 1437, d: { siteId: siteId } };
                console.log(`📤 发送1437指令移动到城市: ${JSON.stringify(payload)}`);
                this.ws.send(JSON.stringify(payload));

                const timeout = setTimeout(() => {
                    const err = new Error(`等待1437响应超时, siteId=${siteId}`);
                    if (this.currentRequest && this.currentRequest.reject) {
                        this.currentRequest.reject(err);
                    }
                    this.currentRequest = null;
                }, timeoutMs);

                this.currentRequest = {
                    type: 'move',
                    siteId,
                    resolve,
                    reject,
                    timeout
                };
            } catch (err) {
                reject(err);
            }
        });
    }

    // 发送713指令获取NPC集群详情
    async getNPCClusterDetails(npcId, timeoutMs = 5000) {
        return new Promise((resolve, reject) => {
            try {
                if (this.currentRequest) {
                    return reject(new Error('上一个请求尚未完成'));
                }

                const payload = { c: 713, d: { id: npcId } };
                console.log(`📤 发送713指令获取NPC详情: ${JSON.stringify(payload)}`);
                this.ws.send(JSON.stringify(payload));

                const timeout = setTimeout(() => {
                    const err = new Error(`等待713响应超时, npcId=${npcId}`);
                    if (this.currentRequest && this.currentRequest.reject) {
                        this.currentRequest.reject(err);
                    }
                    this.currentRequest = null;
                }, timeoutMs);

                this.currentRequest = {
                    type: 'npc_detail',
                    npcId,
                    resolve,
                    reject,
                    timeout
                };
            } catch (err) {
                reject(err);
            }
        });
    }

    // 处理WebSocket消息
    handleMessage(message) {
        try {
            // 处理1437移动响应
            if (message.act_id === 1437 && this.currentRequest && this.currentRequest.type === 'move') {
                clearTimeout(this.currentRequest.timeout);
                const { resolve, siteId } = this.currentRequest;
                this.currentRequest = null;

                if (message.code === 0) {
                    console.log(`✅ 成功移动到城市 ${siteId}`);
                    resolve(message);
                } else {
                    reject(new Error(`移动失败: ${message.msg}`));
                }
                return;
            }

            // 处理200 NPC集群列表响应
            if (message.act_id === 200 && message.npclist) {
                console.log(`📋 收到NPC集群列表，共${message.npclist.length}个:`);
                message.npclist.forEach(npc => {
                    console.log(`  - ${npc.id}: ${npc.name} (类型:${npc.typeId})`);
                });

                // 保存当前城市的NPC列表
                if (this.currentCity) {
                    this.npcClusters[this.currentCity.id] = {
                        city: this.currentCity,
                        npcList: message.npclist,
                        npcDetails: {}
                    };
                }

                // 准备查询每个NPC的详情
                this.pendingNPCs = message.npclist;
                return;
            }

            // 处理713 NPC详情响应
            if (message.act_id === 713 && this.currentRequest && this.currentRequest.type === 'npc_detail') {
                clearTimeout(this.currentRequest.timeout);
                const { resolve, npcId } = this.currentRequest;
                this.currentRequest = null;

                if (message.code === 0 && message.data) {
                    console.log(`✅ 获取NPC ${npcId} 详情成功，共${message.data.length}个怪物:`);
                    message.data.forEach(monster => {
                        console.log(`    - ${monster.name} (等级:${monster.lvl}, 数量:${monster.num})`);
                    });

                    // 保存NPC详情
                    if (this.currentCity && this.npcClusters[this.currentCity.id]) {
                        this.npcClusters[this.currentCity.id].npcDetails[npcId] = message.data;
                    }

                    resolve(message);
                } else {
                    console.log(`❌ 获取NPC ${npcId} 详情失败: ${message.msg}`);
                    resolve(null);
                }
                return;
            }

        } catch (error) {
            console.error('❌ 处理消息失败:', error.message);
        }
    }

    // 采集单个城市的NPC数据
    async collectCityNPCs(city) {
        console.log(`\n🏙️ 开始采集城市: ${city.name} (ID: ${city.id})`);
        this.currentCity = city;

        try {
            // 1. 移动到城市
            await this.moveToCity(city.id);
            await this.delay(1000);

            // 2. 等待200响应获取NPC列表
            console.log('⏳ 等待NPC集群列表...');
            await this.delay(2000);

            // 3. 查询每个NPC的详情
            if (this.pendingNPCs.length > 0) {
                console.log(`🔍 开始查询${this.pendingNPCs.length}个NPC的详情...`);

                for (const npc of this.pendingNPCs) {
                    try {
                        await this.getNPCClusterDetails(npc.id);
                        await this.delay(500); // 避免请求过于密集
                    } catch (error) {
                        console.log(`⏭️ 跳过NPC ${npc.id}: ${error.message}`);
                    }
                }
            }

            console.log(`✅ 城市 ${city.name} 采集完成`);

        } catch (error) {
            console.log(`❌ 城市 ${city.name} 采集失败: ${error.message}`);
        }
    }

    // 采集所有城市的NPC数据
    async collectAllCities() {
        console.log('🚀 开始采集所有城市的NPC集群数据...');

        for (const city of this.citySites) {
            await this.collectCityNPCs(city);
            await this.delay(1000); // 城市间间隔
        }

        console.log('🎉 所有城市NPC数据采集完成');
    }

    // 保存数据到文件
    saveToFile() {
        try {
            const outputDir = './output';
            if (!fs.existsSync(outputDir)) {
                fs.mkdirSync(outputDir, { recursive: true });
            }

            const filePath = path.join(outputDir, 'yeguai0923.json');
            const jsonString = JSON.stringify(this.npcClusters, null, 2);

            fs.writeFileSync(filePath, jsonString, 'utf8');

            console.log(`💾 数据已保存到: ${filePath}`);
            console.log(`📊 采集统计:`);
            console.log(`   - 城市数量: ${Object.keys(this.npcClusters).length}`);

            let totalNPCs = 0;
            let totalMonsters = 0;
            Object.values(this.npcClusters).forEach(cityData => {
                totalNPCs += cityData.npcList ? cityData.npcList.length : 0;
                Object.values(cityData.npcDetails).forEach(monsters => {
                    totalMonsters += monsters.length;
                });
            });

            console.log(`   - NPC集群数量: ${totalNPCs}`);
            console.log(`   - 怪物种类数量: ${totalMonsters}`);

            return {
                success: true,
                filePath: filePath,
                stats: {
                    cities: Object.keys(this.npcClusters).length,
                    npcs: totalNPCs,
                    monsters: totalMonsters
                }
            };

        } catch (error) {
            console.error('❌ 保存文件失败:', error.message);
            return {
                success: false,
                error: error.message
            };
        }
    }

    // 延迟工具方法
    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    // WebSocket连接和采集流程
    async runCollection() {
        console.log('🚀 开始NPC集群数据采集...\n');

        try {
            // 1. 从数据库获取城市列表
            await this.getCitySitesFromDB();

            // 2. 建立WebSocket连接
            console.log('\n🔌 建立WebSocket连接...');
            const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${CONFIG.token}`;
            this.ws = new WebSocket(wsUrl);

            await new Promise((resolve, reject) => {
                this.ws.on('open', async () => {
                    console.log('✅ WebSocket连接成功');

                    // 保持连接的基础指令
                    this.ws.send(JSON.stringify({ c: 3 }));
                    this.ws.send(JSON.stringify({ "c": 5, "d": { "roleId": 12933 } }));
                    this.ws.send(JSON.stringify({ c: 100 }));

                    // 心跳
                    setInterval(() => {
                        this.ws.send(JSON.stringify({ c: 100 }));
                    }, 20000);

                    resolve();
                });

                this.ws.on('error', (error) => {
                    console.log('❌ WebSocket连接失败:', error.message);
                    reject(error);
                });

                this.ws.on('message', (data) => {
                    try {
                        const message = JSON.parse(data);
                        this.handleMessage(message);
                    } catch (error) {
                        console.error('❌ 消息解析失败:', error.message);
                    }
                });
            });

            // 3. 开始采集
            await this.delay(2000);
            await this.collectAllCities();

            // 4. 保存数据
            this.saveToFile();

        } catch (error) {
            console.error('❌ 采集过程中发生错误:', error.message);
        } finally {
            if (this.ws) {
                this.ws.close();
                console.log('🔌 WebSocket连接已关闭');
            }
        }
    }
}

// 运行采集
async function main() {
    console.log('🎯 NPC集群数据采集模式');
    console.log('   采集流程：获取城市列表 → 移动到城市 → 获取NPC列表 → 获取NPC详情 → 保存数据\n');

    const collector = new NPCClusterCollector();
    await collector.runCollection();
}

// 如果直接运行此脚本
if (require.main === module) {
    main().catch((error) => {
        console.error('💥 采集脚本执行失败:', error.message);
        process.exit(1);
    });
}

module.exports = NPCClusterCollector;
